package cn.tedu.mall.service.impl;

import cn.tedu.mall.pojo.product.vo.SkuStandardVO;
import cn.tedu.mall.pojo.seckill.model.SeckillSku;
import cn.tedu.mall.pojo.seckill.vo.SeckillSkuVO;
import cn.tedu.mall.product.service.seckill.IForSeckillSkuService;
import cn.tedu.mall.seckill.mapper.SeckillSkuMapper;
import cn.tedu.mall.seckill.service.ISeckillSkuService;
import cn.tedu.mall.seckill.utils.SeckillCacheUtils;
import org.apache.commons.lang.math.RandomUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.TimeUnit;

@Service
public class SeckillSkuServiceImpl implements ISeckillSkuService {


    @Autowired
    private SeckillSkuMapper skuMapper;
    // dubbo 查询sku详细信息的生产者
    @DubboReference
    private IForSeckillSkuService dubboSkuService;
    // 保存到redis中
    @Autowired
    private RedisTemplate redisTemplate;


    // 根据spuId查询所有秒杀Sku列表
    @Override
    public List<SeckillSkuVO> listSeckillSkus(Long spuId) {
        // 根据spuId查询所有sku列表的方法
        List<SeckillSku> seckillSkus = skuMapper.findSeckillSkusBySpuId(spuId);
        //       声明包含sku详情和秒杀
        List<SeckillSkuVO> seckillSkuVOS = new ArrayList<>();
        // 遍历数据库查询出来的所有sku列表
        for (SeckillSku sku : seckillSkus){
            //
            SeckillSkuVO seckillSkuVO = null;
            //  获取skuId保存在变量中
            Long skuId = sku.getSkuId();
            //  检查Redis是否包含在对象中,准备key
            String seckillSkuVOKey = SeckillCacheUtils.getSeckillSkuVOKey(skuId);
            //    是否含有key
            if (redisTemplate.hasKey(seckillSkuVOKey)){
                seckillSkuVO =(SeckillSkuVO) redisTemplate.boundValueOps(seckillSkuVOKey).get();
            }else {
                //  没有key需要 从数据库中查询保存到Rdis中,dubbo根据skuId 查询sku详细信息
                SkuStandardVO skuStandardVO = dubboSkuService.getById(skuId);
                // 将seckillSkuVO实例化后赋值
                seckillSkuVO = new SeckillSkuVO();
                BeanUtils.copyProperties(skuStandardVO,seckillSkuVO);
                // 将秒杀信息赋值给seckillSkuVO 包含详情信息和秒杀信息
                seckillSkuVO.setStock(sku.getSeckillStock());
                seckillSkuVO.setSeckillPrice(sku.getSeckillPrice());
                seckillSkuVO.setSeckillLimit(sku.getSeckillLimit());
                // 将对象保存到redis中
                redisTemplate.boundValueOps(seckillSkuVOKey).set(seckillSkuVO,60*60*24*1000+
                        RandomUtils.nextInt(2*60*60*1000), TimeUnit.MILLISECONDS);
            }
            seckillSkuVOS.add(seckillSkuVO);
        }
        return seckillSkuVOS;
    }


}
